import AudioPlayer from "../core/AudioPlayer"; 
import MathUtil from "./MathUtil"; 


let Const  = {
    ErShiYi : Math.pow(10,21),
    ShiBaWei : Math.pow(10,18),
    ShiWuWei : Math.pow(10,15),
    ShiErWei : Math.pow(10,12),
    JiuWei : Math.pow(10,9),
    LiuWei : Math.pow(10,6),
    SanWei : Math.pow(10,3), 
}
/**
 * 游戏逻辑工具
 */
 
export default class Tools{

    static serverTime:number = 0;
    static lastSendTime:number = 0;

    static playMusic(url){
        Tools.loadRes(url, cc.AudioClip,(audio)=>{  
            AudioPlayer.playMusic(audio);
        }) 
    } 
    static playEffect(url,isLoop =false){
        Tools.loadRes(url, cc.AudioClip,(audio)=>{  
            AudioPlayer.playEffect(audio,isLoop);
        }) 
    } 
    /**
     * 获取当前系统时间
     * @param isMs 是否毫秒
     */
    static getTime(isMs?:boolean){
        if(isMs)return Math.floor(Date.now());
        return Math.floor(Date.now() /1000);
    }

    /**
     * 获取服务器时间
     */
    static getServerTime(){ 
        return Tools.serverTime + Math.floor(Date.now() / 1000) - Tools.lastSendTime
    }
 
    /**获取起点坐标到终点坐标的角度 */
	static getAngleWith2Pos(startPos: cc.Vec3, endPos: cc.Vec3) {
		var angle = Math.atan2((endPos.y-startPos.y),(endPos.x-startPos.x))
        return angle*(180/Math.PI)
        
        
        //let hudu = cc.v2(endPos.sub(startPos)).signAngle(cc.v2(0, 1));
		//return -(180 * hudu) / Math.PI;
	}

    /**获取2点之间的距离 */
	static getDisWith2Pos(pos1: cc.Vec3, pos2: cc.Vec3) {
		return pos1.sub(pos2).len();
	}
 

     //保留小数点后几位
    static  toFixed(number,fractionDigits){
        var times = Math.pow(10, fractionDigits);
        var roundNum = Math.round(number * times) / times;
        return roundNum.toFixed(fractionDigits);
    }

      //获得单位 只展示3位
    static  getCompany(value, pos:number = 0){  
        if(!value) return 0;
        pos = Tools.isEmpty(pos) ? 0:pos;
      
        var str = value
        if(value >= Const.ErShiYi ){
            //21位  K
            str = Tools.toFixed(value/Const.ErShiYi,pos) + "b" 
        }
        else if(value >= Const.ShiBaWei){
            //18位  K
            str = Tools.toFixed(value/Const.ShiBaWei,pos) + "e" 
        }else if(value >= Const.ShiWuWei){
            //15位  K
            str = Tools.toFixed(value/Const.ShiWuWei,pos) + "p" 
        }else if(value >= Const.ShiErWei){
            //12位  K
            str = Tools.toFixed(value/Const.ShiErWei,pos) + "t" 
        }else if (value >= Const.JiuWei){
            //9位  K
            str = Tools.toFixed(value/Const.JiuWei,pos) + "g" 
        }else if( value >= Const.LiuWei){ 
            //6位  K
            str = Tools.toFixed(value/Const.LiuWei,pos) + "m" 
        } else if( value >= Const.SanWei ){ 
            //3位  K
            str = Tools.toFixed(value/Const.SanWei,pos) + "k" 
        }else{
            str = Tools.toFixed(value,0)
        }
        return str;
    }


    //是否为空
    static isEmpty = (str: any): boolean => {
        if (
          str === null ||
              str === '' ||
              str === undefined ||
              str.length === 0
        ) {
          return true
        } else {
          return false
        }
    }; 


    static isValid(param){
        return !Tools.isEmpty(param)
    }


    static getValid(param,v){
        if(Tools.isEmpty(param)){
            return v
        }
        return param;
    }


    static clone(dest, src) {
        for (var property in src) {
            if (typeof src[property] === "object" && src[property] !== null && dest[property]) {
                Tools.clone(dest[property], src[property]);
            } else {
                dest[property] = src[property];
            }
        }
    };

      
    // 跨天检查
    static checkOtherDay(t1, t2, rt) {
        if (Tools.isEmpty(t1)) {
            return false;
        }
        t2 = t2 || 0;
        rt = rt || 0;

        if (Math.abs(t2 - t1) > 86400) {
            return true;
        }
        return t2 > Tools.figureResetTime(t1, rt);
    }

    // 计算重置点
    static  figureResetTime(t1, rt) {
        var rH = Math.floor(rt / 60 / 60);
        var rM = Math.floor(rt / 60 % 60);
        var rS = Math.floor(rt % 60);
        var dd = new Date(2099, 1, 1, rH, rM, rS);
        var rd = dd.getTime() / 1000;
        return t1 + ((rd - t1) % 86400);
    }

    
    /**
     * @description button置灰节点
     * @param btnNode  btn按钮组件
     * @param isEnable  是否禁用
     */
   static grayButton(btnComp:cc.Button,isEnable:boolean){
        if(isEnable){
            btnComp.interactable = false; 
            btnComp.enableAutoGrayEffect = true;
        }else{
            btnComp.interactable = true; 
            btnComp.enableAutoGrayEffect = false;
        }
    }

    //获取发布后的资源路径
    static getUrl(url){
        url = cc.url.raw(url);
        if(cc.loader.md5Pipe){
            url = cc.loader.md5Pipe.transformURL(url);
        } 
        try {
            //@ts-ignore
            wx.getFileSystemManager.accessSync(url)
        } catch (error) {
            url=(<any>window).wxDownloader.REMOTE_SERVER_ROOT + "/" +url;
        }

        return url;
    }

    /**
     * 
     * @param aniName 重置懂初始化状态
     */
    static resetAni(aniObj, aniName?:string){
        let ani:cc.Animation = aniObj;
        let curName:string = aniName || ani.currentClip.name ;
        ani.play(curName,0);
        ani.sample(curName)
        ani.stop();
    } 


    /** 把 node1移动到 node2的位置 */
    static moveN1toN2(node1, node2) {
        node1.position = node1.parent.convertToNodeSpaceAR(node2.parent.convertToWorldSpaceAR(node2.position))
    }

    /** 获取把 node1移动到 node2位置后的坐标 */
    static convertNodeSpaceAR(node1, node2) {
        return node1.parent.convertToNodeSpaceAR(node2.parent.convertToWorldSpaceAR(node2.position))
    }

    /**
     * 对比版本号
     * @param v1 1.0.2
     * @param v2 1.0.3
     */
    static compareVersion(v1, v2) {
        v1 = v1.split('.');
        v2 = v2.split('.');
        var len = Math.max(v1.length, v2.length);
        while (v1.length < len) {
            v1.push('0')
        }
        while (v2.length < len) {
            v2.push('0')
        }
        for (var i = 0; i < len; i++) {
            var num1 = parseInt(v1[i]);
            var num2 = parseInt(v2[i]);
            if (num1 > num2) {
                return 1
            } else if (num1 < num2) {
                return -1
            }
        }
        return 0
    }

   static getRanomList(){
        let arr = []
        while (arr.length < 4) {
            arr.push(MathUtil.getRandomInt(1,539)) 
        }
        return arr;
    }


    static dateFormat(fmt = 'YYYY-mm-dd HH:MM:SS', date = new Date()) {
        let ret
        const opt = {
          'Y+': date.getFullYear().toString(), // 年
          'm+': (date.getMonth() + 1).toString(), // 月
          'd+': date.getDate().toString(), // 日
          'H+': date.getHours().toString(), // 时
          'M+': date.getMinutes().toString(), // 分
          'S+': date.getSeconds().toString() // 秒
        }
        for (const k in opt) {
          ret = new RegExp('(' + k + ')').exec(fmt)
          if (ret) {
            fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0')))
          }
        }
        return fmt
      } 
    
    /**
     * 获取用户名字
     */
    static getPlayerName(name:string){
        if(!name){
            return "神秘游客";
        } 
        if(name.length > 6){
            return name.substring(0,6) +"...";
        }

        return name;
    }
    
    //适配
    static adapter(node){
        //等比缩放
        if(typeof(node) == "string") return;
        if(!node)return;
        if(!cc.isValid(node))return;
        let minX = cc.winSize.width/1126;
        let minY = cc.winSize.height/2436;
        node.scale = minX < minY ?minY:minX; 
    }


    static find(node:cc.Node,path:string,type:any=null){
        let getNode = cc.find(path,node)
        if(getNode){
            if(type)
                return getNode.getComponent(type)
            else
                return getNode
        }
        return null;
    } 


    //异步等待加载 
    static async load(path:string){ 
        let node = null;
        if(!cc.isValid(node)){
            await new Promise(res => {
                cc.resources.load(path,cc.Prefab,(error: Error, prefab: cc.Prefab) => {
                    if (!error) { 
                        node = cc.instantiate(prefab)
                    }
                    res(node);
                });
            });
        } 
        if (!cc.isValid(node)) {
            cc.warn('[加载模块失败]', '加载模块失败', path);  
            return null
        }
        return node;
    }

    /**
     * 加载指定资源
     * @path 资源路径
     * @type 资源类型
     * @call 加载回调
     */
    static loadRes(path:string, type: typeof cc.Asset,call:Function){
        cc.resources.load(path,type,(err,sp)=>{
            if(err){
                console.log(err,path)
                return
            }
            call(sp);
        });
    }

     /**
     * 加载指定资源
     * @path 资源路径
     * @type 资源类型 
     * return 返回资源
     */
    static async loadResAsync(path:string, type: typeof cc.Asset){
        return new Promise<cc.Asset>((resolve, reject) => {
            cc.resources.load(path,type,(err,sp)=>{
                if(err){
                    console.error(err);
                    resolve(null);
                    return
                }
                resolve(sp);
            });
        });
    }

    //异步加载模型
    /**
     * 加载spine数据
     * @param spinePath spine资源路径
     * @param baseSpineNode 父节点spine
     */
	static async loadModel(spinePath,baseSpineNode?:sp.Skeleton){
        let spineNode:sp.Skeleton = baseSpineNode;
		await new Promise(res => {
			Tools.loadRes(spinePath,sp.SkeletonData,(skeleton:sp.SkeletonData) => { 
                if(skeleton){
                    if(!baseSpineNode){ 
                        let node = new cc.Node('spineNode')
                        spineNode = node.addComponent(sp.Skeleton) 
                    }
                    spineNode.skeletonData = skeleton;
                    spineNode.premultipliedAlpha = false; 
                    spineNode.timeScale = 1.0;
                }
				res(spineNode);
			});
		});
		if (!cc.isValid(spineNode) && !cc.isValid(spineNode.node)) {
            cc.warn('[Entity:loadModel]', '加载模块失败', spinePath);  
        }
        return spineNode;
	}
  

    static addPreZero(num){ 
        let m=Math.floor(num/60%60);
        let s=Math.floor(num%60);  
        return "{0}:{1}".format( ('00'+m).slice(-2), ('00'+s).slice(-2))
    }

    static addPreZeroEx(num){ 
        let h=Math.floor(num/60/60)
        let m=Math.floor(num/60%60);
        let s=Math.floor(num%60);  
        return "{0}:{1}:{2}".format( ('00'+h).slice(-2),('00'+m).slice(-2), ('00'+s).slice(-2))
    }

    static getResetTimeByHour( num ) {
        let h=Math.floor(num/60/60)
        let m=Math.floor(num/60%60);
        let s=Math.floor(num%60);  
        return "{0}:{1}:{2}".format( h, ('00'+m).slice(-2), ('00'+s).slice(-2))
    }

    // 取得倒计时( 只取最大单位，最大到天 )
    static getResetTime( num ) {
        let d = Math.floor( num/60/60/24 );
        let h = Math.floor( num/60/60%24 );
        let m = Math.floor( num/60%60 );
        let s=Math.floor(num%60);
        if ( d > 0 ) {
            return "{0}天{1}小时{2}分{3}秒".format( d, ('00'+h).slice(-2), ('00'+m).slice(-2), ('00'+s).slice(-2) );
        } else if ( h > 0 ) {
            return "{0}小时{1}分{2}秒".format( ('00'+h).slice(-2), ('00'+m).slice(-2), ('00'+s).slice(-2) );
        } else if ( m > 0 ) {
            return "{0}分{1}秒".format( ('00'+m).slice(-2), ('00'+s).slice(-2) );
        } else {
            return "{0}秒".format( ('00'+s).slice(-2) );
        }
    };
   
    static bytesToSize(bytes) {    
        if (bytes === 0) return '0 B';   
        var k = 1024, // or 1024        
        sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],        
        i = Math.floor(Math.log(bytes) / Math.log(k));    
        return (bytes / Math.pow(k, i)).toPrecision(3) + '' + sizes[i];
    }

     //设置玩家名字，限制长度
     static setPlayerName(str, n) {
        if ( Tools.isEmpty(str) || str == "" || str == "null") {
            return "神秘人";
        }
        //str = stripscript(str);//取消名字的屏蔽
        n = n || 8;
        var r = /[^\x00-\xff]/g;
        if (str.replace(r, "mm").length <= n) {
            return str;
        }
        var m = Math.floor(n / 2);
        for (var i = m; i < str.length; i++) {
            if (str.substr(0, i).replace(r, "mm").length >= n) {
                return str.substr(0, i) + "...";
            }
        }
        return str;
    };
    
    public static Icon(){
        console.log("                    .::::.");
        console.log("                  .::::::::.");
        console.log("                 :::::::::::  FUCK YOU");
        console.log("             ..:::::::::::'");
        console.log("           '::::::::::::'");
        console.log("             .::::::::::");
        console.log("        '::::::::::::::..");
        console.log("             ..::::::::::::.");
        console.log("           ``::::::::::::::::");
        console.log("            ::::``:::::::::'        .:::.");
        console.log("           ::::'   ':::::'       .::::::::.");
        console.log("         .::::'      ::::     .:::::::'::::.");
        console.log("        .:::'       :::::  .:::::::::' ':::::.");
        console.log("       .::'        :::::.:::::::::'      ':::::.");
        console.log("      .::'         ::::::::::::::'         ``::::.");
        console.log(" ...:::           ::::::::::::'              ``::.");
        console.log(" ```` ':.          ':::::::::'                  ::::..");
        console.log("                    '.:::::'                    ':'````..");
    }


}
 
window["Tools"] = Tools;
